use native_tls::TlsConnector;
use std::io::{Read, Write};
use std::net::TcpStream;
use std::time::Duration;
use url::Url;

pub fn parse_qurery_string(query_string: &str) -> Vec<(String, String)> {
    let mut result = Vec::new();
    let mut key = String::new();
    let mut value = String::new();
    let mut in_key = true;
    for c in query_string.chars() {
        if c == '=' {
            in_key = false;
        } else if c == '&' {
            result.push((key, value));
            key = String::new();
            value = String::new();
            in_key = true;
        } else if in_key {
            key.push(c);
        } else {
            value.push(c);
        }
    }
    result
}

pub fn parse_url(_url: &str) {
    let res = url::Url::parse(_url);
    if let Ok(u) = res {
        println!("{:?}", u)
    }
}

pub fn web_http_request(url: &str, method: &str, headers: Vec<&str>, body: &str, time_out: u64)->Result<Vec<u8>,String> {
    if let Ok(url_obj) = Url::parse(url) {
        let mut address = String::new();
        let mut host = String::new();
        let mut path = url_obj.path().to_string();
        let port = url_obj.port().unwrap_or(80);
        let header_lines = headers.join("\r\n");
        if let Some(host_tp) = url_obj.host() {
            address = host_tp.to_string();
            host = host_tp.to_string();
        }
        if url_obj.scheme() == "https" {
            address = format!("{}:443", address);
        }else{
            address = format!("{}:{}", address,port);
        }
        if let Some(query) = url_obj.query() {
            path = format!("{}?{}", path, query);
        }
        if let Ok(mut tcp_stream) = TcpStream::connect(&address) {
           if let Err(e) = tcp_stream
                .set_read_timeout(Some(Duration::from_secs(time_out))){
               return Err(e.to_string());
           }
            let request = format!("{} {} HTTP/1.1\r\n\
                       Host: {}\r\n\
                       Connection: keep-alive\r\n\
                       {}
                       User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36\r\n\
                       \r\n{}",method,path,host,header_lines,body);
            let mut buffer = Vec::<u8>::new();
            if url_obj.scheme() == "https" {
                let connector = TlsConnector::new().unwrap();
                let mut tls_stream = match connector.connect(&host, tcp_stream.try_clone().unwrap()) {
                    Ok(stream) => stream,
                    Err(e) => {
                        return Err(e.to_string());
                    }
                };
                if let Err(e) = tls_stream.write(request.as_bytes()) {
                    return Err(e.to_string());
                }
                loop {
                    let mut buf = [0; 1024];
                    match tls_stream.read(&mut buf) {
                        Ok(n) => {
                            if n == 0 {
                                // 读取完成
                                break;
                            }
                            buffer = [buffer, buf[0..n].to_vec()].concat();
                        }
                        Err(e) => {
                            println!("Read error: {}", e);
                            break;
                        }
                    }
                }
            }else{
                //http
                println!("http");
                let res_write=tcp_stream.write(request.as_bytes());
                if let Err(_)=res_write{
                    return Err("Write error".to_string());
                }
                loop {
                    let mut buf = [0; 1024];
                    match tcp_stream.read(&mut buf) {
                        Ok(n) => {
                            if n == 0 {
                                // 读取完成
                                break;
                            }
                            buffer = [buffer, buf[0..n].to_vec()].concat();
                        }
                        Err(e) => {
                            println!("Read error: {}", e);
                            break;
                        }
                    }
                }
            }
            return Ok(buffer);
        } else {
            return Err(format!("Connect error: {}", address));
        }
    } else {
        return Err("Parse url error".to_string());
    }
}
